﻿// MyProject.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
//公众号：程序员速成 ，内含一辈子都让你感激自己的优质视频教程，欢迎关注

#include <iostream>
#include "Monster.h"

#ifdef _DEBUG   //只在Debug（调试）模式下
#ifndef DEBUG_NEW
#define DEBUG_NEW new(_NORMAL_BLOCK,__FILE__,__LINE__) //重新定义new运算符
#define new DEBUG_NEW
#endif
#endif

//#include <boost/type_index.hpp>
using namespace std;
//#pragma warning(disable : 4996) 

namespace _nmsp1
{
	/*
	//怪物状态枚举值
	enum MonsterState
	{
		MonS_Fer,   //凶悍
		MonS_Worr,  //不安
		MonS_Fear,  //恐惧
		MonS_Dead   //死亡
	};

	//怪物类
	class Monster
	{
	public:
		//构造函数，怪物的初始状态从 凶悍 开始
		Monster(int life) :m_life(life), m_status(MonS_Fer) {}

	public:
		void Attacked(int power) //怪物被攻击，power表示主角对怪物的攻击力（怪物丢失的血量）
		{
			m_life -= power; //怪物剩余的血量
			if (m_status == MonS_Fer) //凶悍
			{
				if (m_life > 400)
				{
					cout << "怪物受到" << power << "点伤害并对主角进行疯狂的反击！" << endl;
					//处理其他动作逻辑
				}
				else if (m_life > 100)
				{
					cout << "怪物受到" << power << "点伤害并对主角进行反击，怪物变得焦躁不安并开始呼唤支援！" << endl;
					m_status = MonS_Worr;
					//处理其他动作逻辑
				}
				else if (m_life > 0)
				{
					cout << "怪物受到" << power << "点伤害，怪物变得恐惧并开始逃跑！" << endl;
					m_status = MonS_Fear;
					//处理其他动作逻辑
				}
				else
				{
					cout << "怪物受到" << power << "点伤害，已经死亡！" << endl;
					m_status = MonS_Dead;
					//处理其他动作逻辑
				}
			}
			else if (m_status == MonS_Worr) //不安 ，血量 <= 400，> 100
			{
				if (m_life > 100)
				{
					cout << "怪物受到" << power << "点伤害并对主角进行反击，并继续急促的呼唤支援！" << endl;					
					//处理其他动作逻辑
				}
				else if (m_life > 0)
				{
					cout << "怪物受到" << power << "点伤害，怪物变得恐惧并开始逃跑！" << endl;
					m_status = MonS_Fear;
					//处理其他动作逻辑
				}
				else
				{
					cout << "怪物受到" << power << "点伤害，已经死亡！" << endl;
					m_status = MonS_Dead;
					//处理其他动作逻辑
				}
			}
			else if (m_status == MonS_Fear) //恐惧
			{
				if (m_life > 0)
				{
					cout << "怪物受到" << power << "点伤害，怪物继续逃跑！" << endl;					
					//处理其他动作逻辑
				}
				else
				{
					cout << "怪物受到" << power << "点伤害，已经死亡！" << endl;
					m_status = MonS_Dead;
					//处理其他动作逻辑
				}
			}
			else  //怪物已经处于死亡状态
			{
				cout << "怪物已死亡，不能再被攻击！" << endl;
			}
		}

	private:
		int   m_life;   //血量（生命）
		MonsterState m_status; //初始状态
	};
	*/
}

int main()
{
	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);//程序退出时检测内存泄漏并显示到“输出”窗口
	
	//第12章 状态（State）模式：行为型，有限状态机
	//状态模式的突出特点：用类来表示状态——策略模式（用类来表示策略）
	//（1）一个基本的状态转换范例
	//有限状态机（Finite State Mache，所写：FSM），简称状态机。
	  //当某个事件（转移条件）发生时，会根据当前状态决定你执行哪种动作，然后进入下一种状态。
	//约定：怪物生命 500。
	  //a) 怪物血量 > 400 ，怪物->凶悍，反击
	  //b) 怪物血量 <= 400， > 100，怪物->不安，反击并呼唤附近其他怪物支援
	  //c) 怪物血量 <= 100，怪物->恐惧，逃跑
	  //d) 怪物血量 <= 0，怪物->死亡，不能再被主角攻击
	//状态类的存在价值：使业务逻辑代码更加清晰和易于维护。

	//（2）引入状态（Status）模式
	//定义：允许一个对象（怪物）在其内部状态改变（比如从凶悍状态改变为不安状态）时改变它的行为（比如从疯狂反击变为反击并互换支援),
	  //对象看起来似乎修改了它的类。
	//UML图中的三种角色
	//a)Context（环境类）：指Monster类。
	//b)State（抽象状态类）：指MonsterStatus子类。
	//c)ConcreteState（具体状态类）：指MonsterStatus_Feroc、MonsterStatus_Worr、MonsterStatus_Fear、MonsterStatus_Dead

	//如下两种情况下，可以考虑使用状态模式：
	//a)对象行为取决于其状态，该对象需要根据其状态来改变行为。
	//b)一个操作中含有庞大的条件分支语句，而这些分支语句的执行依赖于对象的当前状态。

	//当项目中某对象的状态特别时，考虑 查表法——对象状态转换

	//（3）状态类的单件实现方式



	/*
	_nmsp1::Monster monster(500);
	cout << "怪物出生，当前处于凶悍状态，500点血！" << endl;
	monster.Attacked(20);
	monster.Attacked(100);
	monster.Attacked(200);
	monster.Attacked(170);
	monster.Attacked(100);
	monster.Attacked(100);
	*/

	Monster monster(500);
	cout << "怪物出生，当前处于凶悍状态，500点血！" << endl;
	monster.Attacked(20);
	monster.Attacked(100);
	monster.Attacked(200);
	monster.Attacked(170);
	monster.Attacked(100);
	monster.Attacked(100);



	return 0;
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件，或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来，若要再次打开此项目，请转到“文件”>“打开”>“项目”并选择 .sln 文件

